package main

import (
	"fmt"
	"gog7xx/g7xx"
	"io"
	"log"
	"os"
	"strconv"
	"strings"
)

var (
	format    string = ""
	inputfile string
	pkglen    int
)

func g726standard(infile, outfile *os.File) {
	g726buf := make([]byte, pkglen)
	g := g7xx.Init(40000, g7xx.ENCODING_LINEAR, g7xx.PACKING_RIGHT)
	for {
		l, err := infile.Read(g726buf)
		if err == io.EOF {
			break
		}
		pcm := g.Decode(g726buf[:l])
		outfile.Write(pcm)
	}
}

func g726hisi(infile, outfile *os.File) {
	g726buf := make([]byte, pkglen+4)
	g := g7xx.Init(40000, g7xx.ENCODING_LINEAR, g7xx.PACKING_RIGHT)
	for {
		l, err := infile.Read(g726buf)
		if err == io.EOF {
			break
		}
		pcm := g.Decode(g726buf[4:l])
		outfile.Write(pcm)
	}
}

func pcmTog726(infile, outfile *os.File) {
	pcmbuf := make([]byte, pkglen)
	g := g7xx.Init(40000, g7xx.ENCODING_LINEAR, g7xx.PACKING_RIGHT)
	for {
		l, err := infile.Read(pcmbuf)
		if err == io.EOF {
			break
		}
		pcm := g.Encode(pcmbuf[:l])
		outfile.Write(pcm)
	}
}

func pcmTohisig726(infile, outfile *os.File) {
	pcmbuf := make([]byte, pkglen)
	g := g7xx.Init(40000, g7xx.ENCODING_LINEAR, g7xx.PACKING_RIGHT)
	for {
		l, err := infile.Read(pcmbuf)
		if err == io.EOF {
			break
		}
		pcm := g.EncodeHisi(pcmbuf[:l])
		outfile.Write(pcm)
	}
}

func main() {
	arglen := len(os.Args)
	if arglen < 3 {
		log.Fatalln("usage")
	}
	for i := 0; i < arglen-1; i++ {
		if os.Args[i] == "-i" {
			i++
			inputfile = os.Args[i]
		} else if os.Args[i] == "-f" {
			i++
			format = os.Args[i]
		} else if os.Args[i] == "-l" {
			i++
			pkglen, _ = strconv.Atoi(os.Args[i])
		}
	}
	ofpname := os.Args[arglen-1]
	sfp, err := os.Open(inputfile)
	if err != nil {
		log.Fatalln(err)
	}
	defer sfp.Close()
	ofp, err := os.OpenFile(ofpname, os.O_RDWR|os.O_CREATE, 0644)
	if err != nil {
		log.Fatalln(err)
	}
	defer ofp.Close()
	if strings.Contains(inputfile, ".g726") {
		pkglen = 200
		if format == "hisi" {
			g726standard(sfp, ofp)
		} else {
			g726hisi(sfp, ofp)
		}
	} else if strings.Contains(inputfile, ".pcm") {
		pkglen = 640
		if format == "hisi" {
			pcmTohisig726(sfp, ofp)
		} else {
			pcmTog726(sfp, ofp)
		}
	}

	fmt.Println(os.Args, "done")
}
